Adds datastore_index_scan_point_bsatn to C# Runtime#3909
Merged
Conversation
Signed-off-by: rekhoff <r.ekhoff@clockworklabs.io>
Centril
approved these changes
Dec 19, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of Changes
To resolve #3875, we added exact-match unique index point lookup support to the C# bindings by introducing and using
datastore_index_scan_point_bsatn.Previously, generated unique index
Find()was (in at least one codepath) implemented as:datastore_index_scan_range_bsatn) over a BTree bound, thenSingleOrDefault()to collapse the results into a single row.When the scan is empty,
SingleOrDefault()returnsdefault(T). For value-type rows this can manifest as a default-initialized row instead of “missing”, which is what surfaced as “default-ish row” behavior in views.Using
datastore_index_scan_point_bsatnmakes the C# implementation match Rust semantics more closely by performing an exact point lookup and returning:nullwhen no rows are foundSimilarly,
datastore_delete_by_index_scan_point_bsatnwas added and used so deletes-by-unique-key are also exact-match point operations rather than range deletes.Runtime updates were made to utilize point scan in
FindSingle(key)and in both mutable/read-only unique-index paths.To keep this non-breaking for existing modules, codegen now detects whether the table row is a struct or a class and chooses the appropriate base type:
Find()returnsRow?(Nullable<Row>).Find()returnsRow?(nullable reference,nullon miss).API and ABI breaking changes
This change is non-breaking with respect to row type kinds, because class/record table rows continue to work via RefUniqueIndex/ReadOnlyRefUniqueIndex while struct rows use UniqueIndex/ReadOnlyUniqueIndex.
API surface changes:
Find()return type is now nullable (Row?) to correctly represent “missing”.ABI/runtime:
datastore_index_scan_point_bsatn) to be available; the runtime uses point-scan for unique lookup (and point delete for unique delete).Expected complexity level and risk
Low 2
Testing